package com.linrui.basic.service.impl;

import com.linrui.basic.service.IVerifyCodeService;
import com.linrui.basic.utils.VerifyCodeUtils;
import com.linrui.user.domain.Logininfo;
import com.linrui.user.domain.User;
import com.linrui.user.dto.LoginSmsCodeDTO;
import com.linrui.user.dto.RegisterSmsCodeDTO;
import com.linrui.user.mapper.LogininfoMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LogininfoMapper logininfoMapper;
    @Override
    public String getImageCode(String key) throws IOException {
        //生成4为验证码
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        System.out.println(verifyCode);
        //验证吗放入redis，并且3分钟过期时间
        redisTemplate.opsForValue().set("imgVerifyCode_"+key,verifyCode,3, TimeUnit.MINUTES);
        //把验证码合成图片并加密为base64数据进行返回
        String base64Data = VerifyCodeUtils.VerifyCode(100,40,verifyCode);
        return base64Data;
    }

    @Override
    public void sendRegisterSmsCode(RegisterSmsCodeDTO dto) {

        String mobile = dto.getMobile();
        String imageCode = dto.getImageCode();
        String imageCodeKey = dto.getImageCodeKey();
//        // 1 参数校验
//        // 1.1 参数的非空校验
        if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(imageCode) || StringUtils.isEmpty(imageCodeKey)){
            throw new RuntimeException("参数异常，请检查后重新提交");
        }

        String imageCodeRedis = (String)redisTemplate.opsForValue().get("imgVerifyCode_"+imageCodeKey);
        if (StringUtils.isEmpty(imageCodeRedis) || !imageCodeRedis.equalsIgnoreCase(imageCode)){
            throw new RuntimeException("图形验证码错误！");
        }

        Logininfo logininfo = logininfoMapper.findUserByMobile(mobile);
        if (Objects.nonNull(logininfo)){
            throw new RuntimeException("该手机号已被注册，请不要重复注册");
        }
        String smsCodeStr = (String)redisTemplate.opsForValue().get("register_sms_code_"+mobile);
        String smsCode = "";
        if (StringUtils.isEmpty(smsCodeStr)){
            smsCode = VerifyCodeUtils.generateVerifyCode(4);
        }else {
            smsCode = smsCodeStr.split(":")[0];
            long sendTime = Long.parseLong(smsCodeStr.split(":")[1]);
            if (System.currentTimeMillis() - sendTime <60*1000){
                throw new RuntimeException("请勿重复发送验证码");
            }
        }
        redisTemplate.opsForValue().set("register_sms_code_"+mobile, smsCode+":"+System.currentTimeMillis(),5,TimeUnit.MINUTES);

        String smsText = "您的验证码是%s,请在%s分钟以内填写";
        System.out.println(String.format(smsText, smsCode,5));
    }

    @Override
    public void sendBinderSmsCode(RegisterSmsCodeDTO dto) {
        String mobile = dto.getMobile();
        if (StringUtils.isEmpty(mobile)){
            throw new RuntimeException("请填写手机号");
        }
        String smsCodeStr = (String)redisTemplate.opsForValue().get("bind_sms_code_"+mobile);
        String smsCode = "";
        if (StringUtils.isEmpty(smsCodeStr)){
            smsCode = VerifyCodeUtils.generateVerifyCode(4);
        }else {
            smsCode = smsCodeStr.split(":")[0];
            long sendTime = Long.parseLong(smsCodeStr.split(":")[1]);
            if (System.currentTimeMillis() - sendTime <60*1000){
                throw new RuntimeException("请勿重复发送验证码");
            }
        }
        redisTemplate.opsForValue().set("bind_sms_code_"+mobile, smsCode+":"+System.currentTimeMillis(),5,TimeUnit.MINUTES);
        String smsText = "您的验证码是%s,请在%s分钟以内填写";
        System.out.println(String.format(smsText, smsCode,5));
    }

    @Override
    public void sendLoginSmsCode(LoginSmsCodeDTO dto) {
        String mobile = dto.getMobile();
        //非空校验
        if (StringUtils.isEmpty(mobile)){
            throw new RuntimeException("请填写手机号");
        }
        //校验数据库里有无这个手机号的用户
        Logininfo logininfo = logininfoMapper.findUserByMobile(mobile);
        if (!Objects.nonNull(logininfo)){
            throw new RuntimeException("该用户不存在");
        }
        String smsCodeStr = (String)redisTemplate.opsForValue().get("login_sms_code"+mobile);
        String smsCode = "";
        //非空校验
        if (StringUtils.isEmpty(smsCodeStr)){
            //为空，重新生成验证码
            smsCode = VerifyCodeUtils.generateVerifyCode(4);
        }else {
            smsCode = smsCodeStr.split(":")[0];
            long sendTime = Long.parseLong(smsCodeStr.split(":")[1]);
            if (System.currentTimeMillis() - sendTime < 60*1000){
                throw new RuntimeException("请勿重复发送手机验证码");
            }
        }
        redisTemplate.opsForValue().set("login_sms_code"+mobile, smsCode+System.currentTimeMillis(),5,TimeUnit.MINUTES);
        String smsText = "您的验证码是%s,请在%s分钟以内填写";
        System.out.println(String.format(smsText, smsCode,5));
    }
}